package util

import "sort"

type Array[ROW any] []ROW

//对数组成员进行遍历并返回新的数组
func ArrayMap [ROW any, RETROW any] (ary []ROW, callback func(row ROW, i int) RETROW) []RETROW {
	ret := make([]RETROW, 0)
	for i, row := range ary {
		ret = append(ret, callback(row, i))
	}

	return ret
}

//对数组成员进行遍历和替换
func ArrayMapRef [ROW any] (ary *[]ROW, callback func(row ROW, i int) ROW) {
	for i, row := range *ary {
		(*ary)[i] = callback(row, i)
	}
}

//迭代上一次计算结果
func ArrayReduce [ROW any, RET any] (ary []ROW, ret RET, callback func(ret RET, row ROW, index int) RET) RET {
	for i, row := range ary {
		ret = callback(ret, row, i)
	}

	return ret
}

//过滤数组元素
func ArrayFilter [ROW any] (ary []ROW, callback func(row ROW, index int) bool) []ROW {
	ret := make([]ROW, 0)
	for i, row := range ary {
		if callback(row, i) {
			ret = append(ret, row)
		}
	}

	return ret
}

//测试数组中是否至少有一个元素通过了由提供的函数实现的测试
//通过测试返回true, 否则返回false
func ArraySome [ROW any] (ary []ROW, callback func(row ROW, index int) bool) bool {
	for i, row := range ary {
		if callback(row, i) {
			return true
		}
	}

	return false
}

type ArraySortInterfaceWithIndex [T any] struct {
	Ary []T
	LessCallback func(prev, next T, i, j int) bool
}

func (this ArraySortInterfaceWithIndex[T]) Len() int {
	return len(this.Ary)
}

func (this ArraySortInterfaceWithIndex[T]) Less(i, j int) bool {
	return this.LessCallback(this.Ary[i], this.Ary[j], i, j)
}

func (this ArraySortInterfaceWithIndex[T]) Swap(i, j int) {
	this.Ary[i], this.Ary[j] = this.Ary[j], this.Ary[i]
}

//排序-提供索引序号(改变现有数组)
func ArraySortRefWithIndex [ROW any] (ary []ROW,  lessCallback func(prev ROW, next ROW, prevIndex int, nextIndex int) bool) []ROW {
	sortInterface := ArraySortInterfaceWithIndex[ROW]{
		Ary: ary,
		LessCallback: lessCallback,
	}
	sort.Sort(sortInterface)

	return sortInterface.Ary
}

//排序(改变现有数组)
func ArraySortRef [ROW any] (ary []ROW,  lessCallback func(prev ROW, next ROW) bool) []ROW {
	return ArraySortRefWithIndex(ary,  func(prev, next ROW, pi, ni int) bool {
		return lessCallback(prev, next)
	})
}

//排序-提供索引序号(不改变现有数组)
func ArraySortWithIndex [ROW any] (ary []ROW,  lessCallback func(prev ROW, next ROW, prevIndex int, nextIndex int) bool) []ROW {
	newAry := make([]ROW, len(ary))
	copy(newAry, ary)
	return ArraySortRefWithIndex(newAry, lessCallback)
}

//排序(不改变现有数组)
func ArraySort [ROW any] (ary []ROW,  lessCallback func(prev ROW, next ROW) bool) []ROW {
	return ArraySortWithIndex(ary, func(prev, next ROW, pi, ni int) bool {
		return lessCallback(prev, next)
	})
}

//将数组转成MAP对象
func ArrayToMap [ROW any, MAPKEY AllowMapKey] (ary []ROW, keyCallback func(row ROW) MAPKEY) map[MAPKEY]ROW {
	ret := make(map[MAPKEY]ROW)
	for _, item := range ary {
		key := keyCallback(item)
		ret[key] = item
	}

	return ret
}